﻿define("Main/Controller",
    [
        "Main/DataModel",
        "Main/ConfigurationEditor/ConfigurationEditor",
        "Main/CommandToolbar/CommandToolbar",
        "Main/FileExplorer/FileExplorer",
        "Shared/Dialog/Dialog"
    ],
    function (DataModel, ConfigurationEditor, CommandToolbar, FileExplorer, Dialog) {
        var Controller = function () {

            // Fields
            var _dataModel = null;
            var _menuBar = null, _configurationEditor = null, _commandToolbar = null;
            var _fileExplorer = null, _fileExplorerDialog = null;
            var _this = this;

            // Init
            this.Initialize = function () {

                // Init UIComponents
                _dataModel = new DataModel();
                _dataModel.Initialize();
                _configurationEditor = new ConfigurationEditor($("#configurationEditorContainer"));
                _configurationEditor.Initialize();
                _commandToolbar = new CommandToolbar($("#toolBarContainer"), _dataModel, _this);
                _commandToolbar.Initialize();

                // Setup events and handlers
                _dataModel.ConfigurationInstanceLoaded.AddHandler(new EventHandler(_configurationEditor.OnConfigurationInstanceLoaded));
                _dataModel.ConfigurationInstanceLoaded.AddHandler(new EventHandler(_commandToolbar.OnConfigurationInstanceLoaded));
                _dataModel.ConfigurationInstanceUnloaded.AddHandler(new EventHandler(_configurationEditor.OnConfigurationInstanceUnloaded));
                _dataModel.ConfigurationInstanceUnloaded.AddHandler(new EventHandler(_commandToolbar.OnConfigurationInstanceUnloaded));
            }

            // Public methods
            this.LoadConfigFromExistingModel = function () {
                _dataModel.LoadConfigurationInstance("Hello");
            }
            this.OpenFile = function () {

                // Setup fileExplorer and dialog in which it is shown
                if (_fileExplorer === null && _fileExplorerDialog === null) {

                    // Create fileExplorer instance
                    var fileExplorerContainer = $("<div class='contentWrapper'></div>");
                    _fileExplorer = new FileExplorer(fileExplorerContainer, _dataModel);
                    _fileExplorer.Initialize();
                    _fileExplorer.FileOpenTriggered.AddHandler(new EventHandler(onFileSelectedForOpen));

                    // Create dialog instance
                    _fileExplorerDialog = new Dialog("Open existing model", fileExplorerContainer, { modal: true });
                    _fileExplorerDialog.Initialize();
                }

                _fileExplorer.LoadModelFiles();
                _fileExplorerDialog.Show();
            }

            // Event handlers
            var onFileSelectedForOpen = function (modelFileCLO) {
                _dataModel.LoadConfigurationInstance(modelFileCLO.Name());
                _fileExplorerDialog.Close();
            }
        }


        // Special global class (currently used by certain CLOs when adding new objects to them)
        window.IdentifierProvider = (function () { // "static" class

            // Methods
            function getNewCLOIdentifier(cloType, collection) {

                // Variables
                var identifier = cloType + "_" + collection.GetAbsoluteItemCounter();
                if (collection.ContainsItemWith("Identifier", identifier)) {
                    var i = collection.GetAbsoluteItemCounter();
                    do {
                        i = i + 1;
                        identifier = cloType + "_" + i;
                    } while (collection.ContainsItemWith("Identifier", identifier));
                }
                return identifier;
            }
            function setupIdentifier(clo, parentCLO) { // parentCLO can be the FeatureModel or the Feature (if an attribute is passed as the clo)

                // If the clo to be added doesnt have an identifier, provide it with one
                if (clo.Identifier !== undefined && clo.Identifier() === null) {

                    var collection = parentCLO[clo.GetType() + "s"]; // get the collection corresponding to the type of the given CLO 
                    var autoGeneratedIdentifier = getNewCLOIdentifier(clo.GetType(), collection);

                    clo.Identifier(autoGeneratedIdentifier);
                    if (clo.Name !== undefined)
                        clo.Name(autoGeneratedIdentifier);

                }
            }

            // Public methods
            return {
                SetupIdentifier: setupIdentifier
            };
        })();


        return Controller;
    });

